import java.util.*;

//栈_基本计算器II（I的难度远超II，基础部分讲II，后边可能会讲I，也可以自己先拓展）
//https://leetcode.cn/problems/basic-calculator-ii/
public class Test {
    public static void main(String[] args) {
        Solution s = new Solution();
        String sss = " 3+5 / 2 ";
         int ret = s.calculate(sss);
         System.out.println(ret);
    }
}

//Try1
//class Solution {
//    public int calculate(String s) {
//        //
//        //int[] stack = new int[s.length()];
//        Stack<Integer> stack = new Stack<Integer>();
//        char op = '+';
//        for (int i = 0; i < s.length(); i++) {
//            char c = s.charAt(i);
//
//            //遇到操作符，更新操作符，并执分情况执行对应操作
//            if(c == '+' || c == '-' || c == '*' || c == '/' ){
//                op = c;
//                continue;
//            }
//
//            //遇到数字，提取数字，再根据操作符，分情况执行对应操作
//            //(1)提取数字
//            int tmp = 0;
////            while(!(c == '+' || c == '-' || c == '*' || c == '/')){
////                tmp = tmp * 10 + c;
////                i++;
////            }
//            do{
//                tmp = tmp * 10 + c - '0';
//                i++;
//                c = s.charAt(i);
//            }while(!(c == '+' || c == '-' || c == '*' || c == '/'));
//            if (op == '+') {
//                stack.push(tmp);
//            } else if (op == '-') {
//                stack.push(-tmp);
//            } else if (op == '*') {
//                int n = stack.pop();
//                stack.push(tmp * n);
//            } else if (op == '/') {
//                int n = stack.pop();
//                stack.push(n / tmp);
//
//            }
//        }
//
//        int ret = 0;
//        while(stack.size() > 0){
//            ret += stack.pop();
//        }
//        return ret;
//
//    }
//}

//方法一：听完老师讲的思路，自己写的（改了好几遍，细节一下还是考虑不全）
/*class Solution {
    public int calculate(String s) {
        //
        //int[] stack = new int[s.length()];
        Stack<Integer> stack = new Stack<Integer>();
        char op = '+';
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if(c == ' '){
                continue;
            }

            //遇到操作符，更新操作符，并执分情况执行对应操作
            if(c == '+' || c == '-' || c == '*' || c == '/' ){
                op = c;
                continue;
            }

            //遇到数字，提取数字，再根据操作符，分情况执行对应操作
            //(1)提取数字
            int tmp = 0;
            while(!(c == '+' || c == '-' || c == '*' || c == '/')&&c!=' '){
                tmp = tmp * 10 + (c - '0');
                i++;
                if(i>=s.length()){

                    break;
                }
                c = s.charAt(i);

            }
            i--;
            *//*do{
                tmp = tmp * 10 + c - '0';
                i++;
                if(i<s.length()){
                    c = s.charAt(i);
                }
            }while(!(c == '+' || c == '-' || c == '*' || c == '/')&&(i<(s.length())));*//*
            if (op == '+') {
                stack.push(tmp);
            } else if (op == '-') {
                stack.push(-tmp);
            } else if (op == '*') {
                int n = stack.pop();
                stack.push(tmp * n);
            } else if (op == '/') {
                int n = stack.pop();
                stack.push(n / tmp);

            }
        }

        int ret = 0;
        while(stack.size() > 0){
            ret += stack.pop();
        }
        return ret;

    }
}*/


//敲了一遍老师的代码
class Solution {
    public int calculate(String _s) {
        //这里
        //很巧妙的地方在于，把多种情况进行了清晰恰当的处理
        //比如：
        //*、/——优先级一样，当下就可以处理，本质上就是可以直接区分开的
        //而对于+、-——都要放到栈里，根据下一个操作符的情况来决定如何处理，不好区分，
        //那么，就干脆，化成一种情况——减法化为加法，减正数化为加负数


        //一些准备工作
        //Deque<Integer> stack = new LinkedList<>();//这个数据结构/集合不太熟悉
        Deque<Integer> stack = new ArrayDeque<>();//这个数据结构/集合不太熟悉

        //后边总是要用到字符的ASCII值，先处理成数组，方便操作（预处理，更方便）
        char[] chars = _s.toCharArray();
        char op = '+';//统一操作——或者说：去特殊性
        int i = 0, n = chars.length;
        int tmp = 0;

        while(i<n){//因为i的增加不是有循环规律的——比如，提取数字的时候，i可能连续增加，所以，用while更合适，随用随加，视（适）情况而定
            //char c = chars[i];//写了半天我发现老师从来就没有用过额外的字符变量，一直都是chars数组
            if(chars[i] ==' '){
                i++;
            }else if(chars[i]>='0' && chars[i]<='9'){
                //提取数字——这里的处理也十分巧妙，利用数学特性
                tmp = 0;

                //while(i<=n && c>='0' && c<='9')——这里的条件，和下边的提取数字的表达式的“条件”，呼应
                while(i<n && chars[i]>='0' && chars[i]<='9'){//这里就体现了i的增加，不适合用for
                    //另外，这里的条件，再if中也出现过，一个条件可以/需要多次使用，锁相关知识中也有一个条件不同含义多次使用的情况
//                    c = chars[i];
//                    tmp = tmp * 10 + (c - '0');//——老师说，这里的处理，把c变量的先进行转化处理，可以防止溢出问题
//                    i++;
                    //上边注释掉的是一种处理方式，但是多了一次c的赋值——第一次，又给c赋值了原值
                    //下面这种处理方式更清晰、合适
                    tmp = tmp * 10 + (chars[i] - '0');
                    i++;
                }

                //提取完数字之后就是对应的操作啦！！！（不是另起一个else，而是就在这个分支里边写！！！）
                if(op == '+'){
                    stack.push(tmp);
                }else if(op == '-'){
                    stack.push(-tmp);
                }else if(op == '*'){
                    stack.push(stack.pop() * tmp);
                }else{
                    stack.push(stack.pop() / tmp);
                }

            }else{//是操作符的情况
                op = chars[i];
                i++;
            }
        }
        //统计结果
        int ret = 0;
        while(!stack.isEmpty()){
            ret += stack.pop();
        }
        return ret;

    }
}






